package com.next.muscu.data;

import java.util.List;

import javax.naming.InitialContext;

import org.hibernate.LockMode;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.next.muscu.old.HibernateUtil;
import com.next.muscu.visual.MainScreen;


public class HibernateQueryTool<T extends MyDataObject> {

	Logger log = LoggerFactory.getLogger(HibernateQueryTool.class);

	private final SessionFactory sessionFactory = getSessionFactory();

	protected SessionFactory getSessionFactory() {
		return HibernateUtil.getSessionFactory();
	}

	public void persist(T transientInstance) {
		log.debug("persisting Exo instance");
		try {
			sessionFactory.getCurrentSession().persist(transientInstance);
			log.debug("persist successful");
		} catch (RuntimeException re) {
			log.error("persist failed", re);
			throw re;
		}
	}

	public void attachDirty(T instance) {
		log.debug("attaching dirty Exo instance");
		try {
			sessionFactory.getCurrentSession().saveOrUpdate(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void attachClean(T instance) {
		log.debug("attaching clean Exo instance");
		try {
			sessionFactory.getCurrentSession().lock(instance, LockMode.NONE);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void delete(T persistentInstance) {
		log.debug("deleting Exo instance");
		try {
			sessionFactory.getCurrentSession().delete(persistentInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	public T merge(T detachedInstance) {
		log.debug("merging Exo instance");
		try {
			T result = (T) sessionFactory.getCurrentSession().merge(
					detachedInstance);
			log.debug("merge successful");
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	public T findById(String className,java.lang.Integer id) {
		log.debug("getting Exo instance with id: " + id);
		try {
			//T instance = (T) sessionFactory.getCurrentSession().get(
			//	 "com.next.data.Exo", id);
			T instance = (T) sessionFactory.getCurrentSession().get(
				 className, id);
			if (instance == null) {
				log.debug("get successful, no instance found");
			} else {
				log.debug("get successful, instance found");
			}
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	public ObservableList<T> findByExample(String className,T instance) {
		log.debug("finding Exo instance by example");
		try {
			List l = sessionFactory.getCurrentSession()
					.createCriteria(className)
					.add(Example.create(instance)).list();
			log.debug("find by example successful, result size: "
					+ l.size());
			ObservableList results = new ObservableList(l);
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}
	
	public ObservableList<T> getAll(String className)
	{
		ObservableList retour = new ObservableList(sessionFactory.getCurrentSession().createQuery("from" +  className).list()); 
		return retour;
	}
}
